package com.supermarket.manage.business.instock.service;

import com.alibaba.fastjson.JSON;
import com.supermarket.manage.common.constant.RedisKeyConstant;
import com.supermarket.manage.common.constant.StockConstant;
import com.supermarket.manage.common.dto.CodeStatus;
import com.supermarket.manage.common.dto.PageBean;
import com.supermarket.manage.common.dto.ResponseResult;
import com.supermarket.manage.common.dto.stock.request.InstockPageParams;
import com.supermarket.manage.common.dto.stock.response.InProdDto;
import com.supermarket.manage.common.dto.stock.response.InstockDto;
import com.supermarket.manage.common.pojo.Instock;
import com.supermarket.manage.common.pojo.MyUser;
import com.supermarket.manage.common.utils.BigDecimalUtil;
import com.supermarket.manage.common.utils.TimeUtil;
import com.supermarket.manage.provider.api.instock.InstockService;
import com.supermarket.manage.provider.api.ucenter.UserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author Faxon
 * @version 1.0
 * @date 2020-03-15 21:57
 **/
@Service
public class InstockBusinessService {

    @Reference(version = "1.0.0")
    private InstockService instockService;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Reference(version = "1.0.0")
    private UserService userService;

    /**
     * 保存入库单
     *
     * @param type
     * @param instock
     * @return
     */
    public ResponseResult<Void> saveInstock(Integer type, Instock instock) {
        instock.setTotalPrice(BigDecimalUtil.formatTwoPoint(instock.getTotalPrice()));
        instock.setActuallyPrice(BigDecimalUtil.formatTwoPoint(instock.getActuallyPrice()));
        instock.setStatus(StockConstant.NOT_DONE);
        Boolean aBoolean;
        String redisKey;
        //新增单据
        if (StringUtils.isBlank(instock.getId())) {
            instock.setType(type);
            aBoolean = instockService.addInstock(instock);
            if (type.equals(StockConstant.SALE)) {
                redisKey = RedisKeyConstant.PURCHASE_IN + instock.getOperator();
            } else {
                redisKey = RedisKeyConstant.RETURN_IN + instock.getOperator();
            }
        }
        //编辑单据
        else {
            Instock newInstock = new Instock();
            newInstock.setId(instock.getId());
            newInstock.setSid(instock.getSid());
            newInstock.setTotalPrice(instock.getTotalPrice());
            newInstock.setActuallyPrice(instock.getActuallyPrice());
            newInstock.setRemark(instock.getRemark());
            newInstock.setUpdated(new Date());
            newInstock.setInstockProds(instock.getInstockProds());
            aBoolean = instockService.updateInstock(newInstock);
            if (type.equals(StockConstant.SALE)) {
                redisKey = RedisKeyConstant.PURCHASE_IN + instock.getId();
            } else {
                redisKey = RedisKeyConstant.RETURN_IN + instock.getId();
            }
        }
        if (aBoolean) {
            //清空对应购物车
            redisTemplate.delete(redisKey);
            return new ResponseResult<>(CodeStatus.OK, "保存成功");
        }
        return new ResponseResult<>(CodeStatus.FAIL, "保存失败");
    }

    /**
     * 完成入库单
     *
     * @param type
     * @param instock
     * @return
     */
    public ResponseResult<Void> doneInstock(Integer type, Instock instock) {
        instock.setTotalPrice(BigDecimalUtil.formatTwoPoint(instock.getTotalPrice()));
        instock.setActuallyPrice(BigDecimalUtil.formatTwoPoint(instock.getActuallyPrice()));
        instock.setStatus(StockConstant.DONE);
        Boolean aBoolean;
        String redisKey;
        //新增单据
        if (StringUtils.isBlank(instock.getId())) {
            instock.setType(type);
            aBoolean = instockService.addInstockAndUpdateStockingNumber(instock);
            if (type.equals(StockConstant.SALE)) {
                redisKey = RedisKeyConstant.PURCHASE_IN + instock.getOperator();
            } else {
                redisKey = RedisKeyConstant.RETURN_IN + instock.getOperator();
            }
        }
        //编辑单据
        else {
            Instock newInstock = new Instock();
            newInstock.setId(instock.getId());
            newInstock.setSid(instock.getSid());
            newInstock.setTotalPrice(instock.getTotalPrice());
            newInstock.setActuallyPrice(instock.getActuallyPrice());
            newInstock.setRemark(instock.getRemark());
            newInstock.setUpdated(new Date());
            newInstock.setInstockProds(instock.getInstockProds());
            aBoolean = instockService.updateInstockAndUpdateStockingNumber(newInstock);
            if (type.equals(StockConstant.SALE)) {
                redisKey = RedisKeyConstant.PURCHASE_IN + instock.getId();
            } else {
                redisKey = RedisKeyConstant.RETURN_IN + instock.getId();
            }
        }
        if (aBoolean) {
            //清空对应购物车
            redisTemplate.delete(redisKey);
            return new ResponseResult<>(CodeStatus.OK, "入库成功");
        }
        return new ResponseResult<>(CodeStatus.FAIL, "入库失败");
    }

    /**
     * 根据id完成入库单
     *
     * @param id
     * @return
     */
    public ResponseResult<Void> doneInstockById(String id) {
        Instock instock = new Instock();
        instock.setId(id);
        instock.setStatus(StockConstant.DONE);
        Boolean aBoolean = instockService.doneInstockById(instock);
        if (aBoolean) {
            return new ResponseResult<>(CodeStatus.OK, "已成功入库");
        }
        return new ResponseResult<>(CodeStatus.FAIL, "入库失败");
    }

    /**
     * 根据id删除入库单
     *
     * @param id
     * @return
     */
    public ResponseResult<Void> deleteInstockById(String id) {
        Boolean aBoolean = instockService.deleteInstockById(id);
        if (aBoolean) {
            return new ResponseResult<>(CodeStatus.OK, "删除成功");
        }
        return new ResponseResult<>(CodeStatus.FAIL, "删除失败");
    }

    /**
     * 条件分页查询入库单
     *
     * @param params
     * @return
     */
    public ResponseResult<PageBean<Instock>> getInstockPageList(InstockPageParams params) {
        PageBean<Instock> pageBean = instockService.getInstockPageList(params);
        if (pageBean == null) {
            return new ResponseResult<>(CodeStatus.FAIL, "查询失败");
        }
        List<MyUser> users = userService.getUserByBuyerId(params.getBuyerId());
        pageBean.getDataList().forEach(i -> {
            users.forEach(u -> {
                if (i.getOperator().equals(u.getId())) {
                    i.setOperatorName(u.getUsername());
                }
            });
        });
        return new ResponseResult<>(CodeStatus.OK, "查询成功", pageBean);
    }

    /**
     * 根据id获取入库单详情
     *
     * @param id
     * @return
     */
    public ResponseResult<InstockDto> getInstockById(String id) {
        InstockDto instock = instockService.getInstockById(id);
        if (instock == null) {
            return new ResponseResult<>(CodeStatus.FAIL, "单据不存在");
        }
        //设置经办人名称
        MyUser user = userService.getUserByUserId(instock.getOperator());
        instock.setOperatorName(user.getUsername());
        //未完成的单据可编辑，将关联商品加入redis
        if (instock.getStatus().equals(StockConstant.NOT_DONE)) {
            String key;
            if (instock.getType().equals(StockConstant.SALE)) {
                key = RedisKeyConstant.PURCHASE_IN + instock.getId();
            } else {
                key = RedisKeyConstant.RETURN_IN + instock.getId();
            }
            redisTemplate.delete(key);
            List<InProdDto> prodList = instock.getInstockProds();
            Map<String, String> map = new HashMap<>(prodList.size());
            prodList.forEach(p -> {
                p.setSubtotal(BigDecimalUtil.formatTwoPoint(p.getSubtotal()));
                map.put(p.getPid(), JSON.toJSONString(p));
            });
            if(map!=null && map.size()>0){
                redisTemplate.opsForHash().putAll(key, map);
            }
        }
        return new ResponseResult<>(CodeStatus.OK, "查询成功", instock);
    }

    /**
     * 获取单据导出数据
     *
     * @param params
     * @return
     */
    public List<Map<String, Object>> getInstockExportMap(InstockPageParams params) {
        List<Instock> instockList = instockService.getInstockList(params);
        List<MyUser> users = userService.getUserByBuyerId(params.getBuyerId());
        instockList.forEach(i -> {
            users.forEach(u -> {
                if (i.getOperator().equals(u.getId())) {
                    i.setOperatorName(u.getUsername());
                }
            });
        });
        List<Map<String, Object>> result = new ArrayList<>();
        instockList.forEach(instock -> {
            Map<String, Object> map = new HashMap<>(8);
            map.put("id", instock.getId());
            if (params.getType().equals(StockConstant.SALE)) {
                map.put("supplier", instock.getSname());
            }
            map.put("operator", instock.getOperatorName());
            map.put("totalPrice", instock.getTotalPrice());
            map.put("actuallyPrice", instock.getActuallyPrice());
            map.put("remark", instock.getRemark());
            if (instock.getStatus().equals(StockConstant.DONE)) {
                map.put("status", "已完成");
            } else {
                map.put("status", "未完成");
            }
            map.put("updated", TimeUtil.formatDate(instock.getUpdated(), TimeUtil.TIME_FORMAT));
            result.add(map);
        });
        return result;
    }
}
